package com.example.xcService.pojo.channels.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.example.xcService.pojo.channels.ChannelResult;
import com.example.xcService.pojo.channels.ChannelService;
import com.example.xcService.pojo.tool.HttpTool;
import lombok.extern.slf4j.Slf4j;

import java.security.MessageDigest;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/*
* 网聚优格
* */
@Slf4j
public class Plugin_ECARD_P016 implements ChannelService {
    @Override
    public ChannelResult Submit(JSONObject apiConfig, Map<String, Object> data) {

        try {
            String AccountVal = String.valueOf(data.get("AccountVal"));
            if (!checkQQNum(AccountVal)){
                return  ChannelResult.error("QQ号码异常");
            }
            // 格式 A1234_90  动态数量
            String[] split = String.valueOf(data.get("SUPProductId")).split("_");
            String itemId = split[0];
            String amount = split[1];
            //必要参数组装
            HashMap<String, Object> params = new HashMap<>();
            params.put("appId", apiConfig.getString("partnerNumber"));
            params.put("outOrderId",data.get("ChannelOrderCode"));
            params.put("uuid",AccountVal);
            params.put("itemId",itemId);
            //params.put("itemFace",data.get("PurchasePrice")); //成本价格

            params.put("amount",amount); //数量
            params.put("appSecret",apiConfig.getString("pubKey"));//秘钥
            /*params.put("callbackUrl",)
            params.put("ext1",) 用户ip
            params.put("ext2",)
            params.put("ext3",)
            params.put("smsCode",)
            */
            //生成时间戳 yyyyMMddHHmmssSSS
            params.put("timestamp",DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS").format(LocalDateTime.now()));
            String url = apiConfig.getString("SubmitURL");
            String sign = md5(createLinkString(params));
            params.put("sign",sign);

            String res = HttpTool.HttpPost2(url, params);
            JSONObject retobj = JSONObject.parseObject(res);
            log.info("响应参数"+JSON.toJSONString(retobj));
            String code = retobj.getString("code");
            String msg = retobj.getString("msg");
           /* String orderId = retobj.getString("orderId");
            String outOrderId = retobj.getString("outOrderId");
            String cost = retobj.getString("cost"); //本次消费
           */
            if(code.equals("00")){
                log.info("订单保存成功，充值中");
                return  ChannelResult.IN_PROCESS("充值中");
            }
            if (code.equals("-16")) {
                log.info("重复下单");
                return ChannelResult.IN_PROCESS("充值中");
            }
            if(code.equals("-22") || code.equals("-23") || code.equals("-99")){
                log.info(code,msg);
                return ChannelResult.IN_PROCESS("充值中");
            }
            log.info(code,msg);
            return  ChannelResult.FAILED("充值失败");
        }catch (Exception e) {
           e.printStackTrace();
            log.error("网聚优格提交订单接口错误：",e);
            return  ChannelResult.error("网聚优格提交订单接口错误");
        }
    }


    @Override
    public ChannelResult QueryBalance(JSONObject apiConfig) {
        System.out.println("成功调用了QueryBalance");
        return  ChannelResult.success("success");
    }


    @Override
    public ChannelResult Query(JSONObject apiConfig, Map<String, Object> data) {
        try {
            LinkedHashMap<String, String> params = new LinkedHashMap<>();
            params.put("appId",apiConfig.getString("partnerNumber"));
            params.put("outOrderId",String.valueOf(data.get("ChannelOrderCode")));
            params.put("timestamp",DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS").format(LocalDateTime.now()));
            params.put("appSecret",apiConfig.getString("pubKey"));//秘钥
            String sign = md5(createLinkString(params));
            params.put("sign",sign);
            String url = apiConfig.getString("QueryURL");

            String res = HttpTool.HttpPost(url, params);
            JSONObject jsonObject = JSONObject.parseObject(res);
            log.info("响应参数："+JSON.toJSONString(jsonObject));
            String code = jsonObject.getString("code");
            String msg = jsonObject.getString("msg");
            String orderStatus = jsonObject.getString("orderStatus"); //订单状态
            String orderDesc = jsonObject.getString("orderDesc");//状态描述
            log.info(code,msg);
            if(code.equals("00")){
               if(orderStatus.equals("2") ){
                    return ChannelResult.success(orderDesc);
               }
               if(orderStatus.equals("1")){
                   return ChannelResult.IN_PROCESS("充值中");
               }
               if (orderStatus.equals("4")) {
                   return ChannelResult.FAILED(orderDesc);
               }
                return ChannelResult.FAILED("充值失败");
            }
           //code不等于0 查询失败，订单状态存疑，改为充值中
            return ChannelResult.IN_PROCESS("充值中");

        }catch (Exception e){
            e.printStackTrace();
            log.error("网聚优格查询订单接口错误：",e);
            return  ChannelResult.error("网聚优格查询订单接口错误");
        }
    }

    @Override
    public ChannelResult Notify(JSONObject apiConfig, Map<String, Object> data) {
        System.out.println("成功调用了Notify");
        return  ChannelResult.success("success");
    }

    /**
     * 把数组所有元素排序，并按照“参数=参数值”的模式用“&”字符拼接成字符串
     * @param params 需要排序并参与字符拼接的参数
     * @return 拼接后字符串
     */
    public static String createLinkString(Map params) {

        List<String> keys = new ArrayList<String>(params.keySet());
        Collections.sort(keys);

        String prestr = "";

        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = String.valueOf(params.get(key));

            if (i == keys.size() - 1) {//拼接时，不包括最后一个&字符
                prestr = prestr + key + "=" + value;
            } else {
                prestr = prestr + key + "=" + value + "&";
            }
        }

        return prestr;
    }

    /**
     * MD5指纹算法
     *
     * @param str
     * @return
     */
    public static String md5(String str) {
        if (str == null) {
            return null;
        }

        try {
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            messageDigest.update(str.getBytes());
            return bytesToHexString(messageDigest.digest());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    /**
     * 将二进制转换成16进制
     * @param src
     * @return
     */
    public static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    private static boolean checkQQNum(String s) {
        boolean flag = false;
        if (s.length() >= 5 && s.length() <= 15 && !s.startsWith("0")) {
            for (int i = 0; i < s.length(); i++) {
                char ch = s.charAt(i);
                if (ch >= '0' && ch <= '9') {
                    flag = true;
                } else {
                    flag = false;
                    break;
                }
            }
        }
        return flag;
    }

}
